/**
 * Enables the nested sortable for the page-structure.
 *
 * Depends on:
 *		jquery
 *		jquery.mjs.nestedSortable.js
 *		action_stack.js
 *		tag_tree.js
 *		setup_ajax.js
 */
$(document).ready(function() {
	var saving = false;

	//Statics
	var STATICS = {
		listContainerId: 'page-structure-content', 
		listId: 'page-structure', 
		listType: 'ol',
		listContentItem: 'div',
		startCollapsed: true,
		enableCollapseButton: true
	};

	//Static HTML
	var HANDLE = $('<span class="handle"></span>');

	//Selectors
	var SAVE_BUTTON = $('#save');
	var UNDO_BUTTON = $('#undo');
	var REDO_BUTTON = $('#redo');
	var ALERT_SAVING = $('#restructure-saving');
	var ALERT_SUCCESS = $('#restructure-success');
	var ALERT_ERROR = $('#restructure-error');

	//Fetch list and id it
	var list = $('#'+STATICS.listContainerId).children(STATICS.listType);
	list.attr('id', STATICS.listId);

	//Add handles
	list.find('li').children().filter(STATICS.listContentItem).prepend(HANDLE);

	//Init help classes
	var actionStack = new ActionStack();
	var treeTagger = new TreeTagger(list, STATICS.startCollapsed, STATICS.enableCollapseButton, STATICS.listType);

	//Store current state in action stack
	var currentHtml = list.html();
	actionStack.storeAction(currentHtml);
	actionStack.markSaved();

	//Enable nested sortable plugin
	enableSortable();

	//Initiate buttons
	refreshButtons();

	/* Listeners */	
	REDO_BUTTON.on('click', function() {
		//Load and restore html
		var storedHtml = actionStack.redoAction();
		list.html(storedHtml);

		//Update button statuses
		refreshButtons();
	});
	
	UNDO_BUTTON.on('click', function() {
		//Load and restore html
		var storedHtml = actionStack.undoAction();
		list.html(storedHtml);

		//Update button statuses
		refreshButtons();
	});
	
	SAVE_BUTTON.on('click', function() {
		saving = true;

		//Update button statuses
		refreshButtons();
		ALERT_SAVING.show();		

		//Save to DB
		applyStateToDB();
	});	

	function trashPage(page) {
		//Delete list-item from view
		page.remove();

		//Update the view
		treeTagger.refreshTags();

		//Store the updated view
		var currentHtml = list.html();
		actionStack.storeAction(currentHtml);

		//Update buttons
		refreshButtons();
	}

	/**
	 *	Stores current state to the database
	 */
	function applyStateToDB() {
		$.ajax({
			type: 'POST',
			url: '#',
			data: {'serialized-structure': list.nestedSortable('serialize')},
			dataType: 'html',
			success: ajaxSuccess,
			error: ajaxError
		});
	}

	function ajaxSuccess(response) {
		//Mark saved
		actionStack.markSaved();

		saving = false;
		//Update button statuses
		refreshButtons();

		ALERT_SUCCESS.show();
	}

	function ajaxError(response) {
		saving = false;
		//Update button statuses
		refreshButtons();

		ALERT_ERROR.show();
	}

	/**
	 *	
	 */
	function refreshButtons() {
		UNDO_BUTTON.attr('disabled', !actionStack.undoAvailable());
		REDO_BUTTON.attr('disabled', !actionStack.redoAvailable());

		//Enable trash buttons (required to re-initialise listening after re-/undo)
		$('.page-trash').on('click', function() {
			trashPage($(this).closest('li'));
		});

		//Navigation => hide alerts
		ALERT_SAVING.hide();
		ALERT_SUCCESS.hide();
		ALERT_ERROR.hide();

		if(saving) {
			SAVE_BUTTON.attr('disabled', true);
			SAVE_BUTTON.text('Saving Book Structure');
			UNDO_BUTTON.attr('disabled', true);
			REDO_BUTTON.attr('disabled', true);
		} else if(actionStack.isSaved()) {
			SAVE_BUTTON.attr('disabled', true);
			SAVE_BUTTON.removeClass('btn-primary');
			SAVE_BUTTON.text('Saved');
		} else {
			SAVE_BUTTON.attr('disabled', false);
			SAVE_BUTTON.addClass('btn-primary');
			SAVE_BUTTON.text('Save Changes');
		}
	}

	/**
	 *	Stores the current state, refreshes buttons and updates tree
	 */
	function updateOnDrop() {
		//Refresh View
		treeTagger.refreshTags();

		//Store the refreshed View
		var currentHtml = list.html();
		actionStack.storeAction(currentHtml);

		//Update buttons
		refreshButtons();
	}

	/**
	 *	Returns wheter the drop is valid or not.
	 *	Returns !saving.
	 */
	function allowDrop() {
		return !saving;
	}


	/**
	 * Enable nested sortable plugin
	 */
	function enableSortable() {
		list.nestedSortable({
			forcePlaceholderSize: true, 	//Forces the height of the 'end up here shadow'
			disableNesting: 'no-nesting',	//The class name marking an item un-nestable
			listType:	STATICS.listType,
			handle: '.handle',//Dragging only possible by this class
			helper: 'clone',
			items: 'li',					//The sortable items
			opacity: .6,					//Transparent drag-action
			placeholder: 'placeholder',		//The class name of the 'end up here shadow'
			errorClass: 'invalid-drop',		//The class name of the invalid 'end up here shadow'
			revert: 250,
			tabSize: 30,					//How big horiz. step when dragging to nest
			tolerance: 'pointer',
			toleranceElement: '> div',
			maxLevels: 0,					//How deep can the tree get (0 => unlimited)
			isTree: true,
			expandOnHover: 500,
			startCollapsed: false,
			update: updateOnDrop,
			isAllowed: allowDrop
		});
	}

	/**
	 *	Prevent user from leaving without confirmation if there are unsaved changes.
	 */
	window.onbeforeunload = function() {
    	if(saving || !actionStack.isSaved()) {
    		return 'You have unsaved changes!';
    	}
	}
});